home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1996 #6 / Amiga Plus CD - 1996 - No. 06.iso / pd / netz / dl / lowlevel.c < prev    next >
C/C++ Source or Header  |  1992-09-02  |  6KB  |  278 lines

  1. /* Copyright (C) 1995, 1996 Zlatko Calusic <maverick@fly.cc.fer.hr>
  2. This file is part of DownLoad, FTP Client
  3.  
  4. The DownLoad is free software; you can redistribute it and/or modify it
  5. under the terms of the GNU General Public License as published by the Free
  6. Software Foundation.
  7.  
  8. The DownLoad is distributed in the hope that it will be useful, but WITHOUT
  9. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  11. more details.
  12.  
  13. You should have received a copy of the GNU General Public License along with
  14. the DownLoad source; see the file COPYING.  If not, write to the Free
  15. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  16.  
  17. #include "dl.h"
  18.  
  19. extern int master, control, data, local;
  20.  
  21. extern int nofatal;
  22.  
  23. extern int aborted, wildcard;
  24.  
  25. extern char host[], file[], buffer[], *matching;
  26.  
  27. extern char localaddr[];
  28.  
  29. extern struct hostent *hptr;
  30.  
  31. extern struct sockaddr_in data_in;
  32. extern int addrlen;
  33.  
  34. extern fd_set fdset;
  35.  
  36. extern struct timeval ttimer;
  37.  
  38. extern struct stat statbuf;
  39.  
  40. int get_response(void)
  41. {
  42.     int size;
  43.     char *pos, *cptr = buffer, *where = buffer;
  44.  
  45.     for (;;)
  46.     {
  47.         timer_on(control);
  48.         if (select(255, &fdset, NULL, NULL, &ttimer) <= 0)
  49.         {
  50.             fputs("Control connection timed out.\n", stderr);
  51.             return ERROR;
  52.         }
  53.         if ((size = read(control, cptr, BUFFER)) < 0)
  54.         {
  55.             perror("Error reading control socket");
  56.             return ERROR;
  57.         }
  58.         else if (!size)
  59.         {
  60.             fputs("Received EOF on control socket.\n", stderr);
  61.             return ERROR;
  62.         }
  63.         cptr += size;
  64.         *cptr = 0;
  65.         while ((pos = strchr(where, '\n')))
  66.         {
  67.             strcpy(pos - 1, "\n");
  68.             fputs(where + 4, stderr);
  69.             if (*(where + 3) == ' ' && atoi(buffer) == atoi(where))
  70.                 switch (atoi(where) / 10)
  71.                 {
  72.                     case 50:
  73.                         if (nofatal)
  74.                             return ERROR;
  75.                     case 55:
  76.                         if (!stat(file, &statbuf) && !statbuf.st_size)
  77.                             unlink(file);
  78.                         fputs("Aborting download ...\n", stderr);
  79.                         aborted = 1;
  80.                         return ERROR;
  81.                     case 12:
  82.                     case 42:
  83.                     case 45:
  84.                     case 53:
  85.                         return ERROR;
  86.                     default:
  87.                         return OK;
  88.                 }
  89.             else
  90.                 where = pos + 1;
  91.         }
  92.     }
  93. }
  94.  
  95. int ftprequest(char *format, char *arg)
  96. {
  97.     int length;
  98.     char string[256];
  99.  
  100.     if (arg)
  101.         sprintf(string, format, arg);
  102.     else
  103.         strcpy(string, format);
  104.     length = strlen(string);
  105.     if (write(control, string, length) != length)
  106.         return ERROR;
  107.     else
  108.         return get_response();
  109. }
  110.  
  111. int establish_connection()
  112. {
  113.     struct sockaddr_in comm_in;
  114.     unsigned long laddr;
  115.  
  116.     if (control)
  117.     {
  118.         close(control);
  119.         control = 0;
  120.     }
  121.     if ((control = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  122.     {
  123.         control = 0;
  124.         perror("Error creating socket");
  125.         return ERROR;
  126.     }
  127.     fprintf(stderr, "Connecting to %s ...", host);
  128.     if ((int) (laddr = inet_addr(host)) == -1 || !strcmp(host, "0"))
  129.         hptr = gethostbyname(host);
  130.     else
  131.         hptr = gethostbyaddr((char *) &laddr, sizeof(laddr), AF_INET);
  132.     if (hptr)
  133.         memcpy(&comm_in.sin_addr, hptr->h_addr_list[0], 4);
  134.     else
  135.     {
  136.         fputs("\nCan't resolve remote hostname, aborting ...\n", stderr);
  137.         aborted = 1;
  138.         return ERROR;
  139.     }
  140.     comm_in.sin_family = AF_INET;
  141.     comm_in.sin_port = htons(21);
  142.     if (connect(control, (struct sockaddr *) &comm_in, sizeof(comm_in)) < 0)
  143.     {
  144.         perror("\nError connecting to server");
  145.         return ERROR;
  146.     }
  147.     fputs(" connected.\n", stderr);
  148.     return get_response();
  149. }
  150.  
  151. int get_port(void)
  152. {
  153.     int port;
  154.     char string[64];
  155.  
  156.     if (master)
  157.     {
  158.         close(master);
  159.         master = 0;
  160.     }
  161.     if ((master = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  162.     {
  163.         master = 0;
  164.         perror("Error creating socket");
  165.         return ERROR;
  166.     }
  167.     data_in.sin_family = AF_INET;
  168.     data_in.sin_addr.s_addr = htonl(0);
  169.     data_in.sin_port = htons(0);
  170.     addrlen = sizeof(data_in);
  171.     if (bind(master, (struct sockaddr *) &data_in, addrlen) < 0)
  172.     {
  173.         perror("Error binding socket");
  174.         return ERROR;
  175.     }
  176.     if (getsockname(master, (struct sockaddr *) &data_in, &addrlen) < 0)
  177.     {
  178.         perror("Error getting port");
  179.         return ERROR;
  180.     }
  181.     port = ntohs(data_in.sin_port);
  182.     if (listen(master, 1) < 0)
  183.     {
  184.         perror("Error listening on data port");
  185.         return ERROR;
  186.     }
  187.     sprintf(string, "PORT %u,%u,%u,%u,%d,%d\r\n", (unsigned char) localaddr[0], (unsigned char) localaddr[1], (unsigned char) localaddr[2], (unsigned char) localaddr[3], (port & 0xff00) >> 8, port & 0xff);
  188.     return ftprequest(string, NULL);
  189. }
  190.  
  191. int accept_data(void)
  192. {
  193.     if (data)
  194.     {
  195.         close(data);
  196.         data = 0;
  197.     }
  198.     addrlen = sizeof(data_in);
  199.     if ((data = accept(master, (struct sockaddr *) &data_in, &addrlen)) < 0)
  200.     {
  201.         data = 0;
  202.         perror("Error accepting connection on data port");
  203.         return ERROR;
  204.     }
  205.     return OK;
  206. }
  207.  
  208. int get_list(void)
  209. {
  210.     int size, header = 0;
  211.     char *found, *fileptr, *cptr = buffer, *where = buffer;
  212.     static char matched[BUFFER];
  213.  
  214.     matching = matched;
  215.     *matching = 0;
  216.     if (!get_port() || !ftprequest("LIST\r\n", NULL) || !accept_data())
  217.         return ERROR;
  218.     for (;;)
  219.     {
  220.         timer_on(data);
  221.         if (select(255, &fdset, NULL, NULL, &ttimer) <= 0)
  222.         {
  223.             fputs("Data connection timed out.\n", stderr);
  224.             return ERROR;
  225.         }
  226.         if ((size = read(data, cptr, BUFFER)) < 0)
  227.         {
  228.             perror("Error reading data socket");
  229.             return ERROR;
  230.         }
  231.         else if (!size)
  232.         {
  233.             if (strlen(matching))
  234.             {
  235.                 fputs("--------------------\n", stderr);
  236.                 wildcard = 1;
  237.                 strcpy(file, strtok(matching, "\r"));
  238.                 return get_response();
  239.             }
  240.             else
  241.             {
  242.                 get_response();
  243.                 fputs("No matches found, aborting ...\n", stderr);
  244.                 aborted = 1;
  245.                 return ERROR;
  246.             }
  247.         }
  248.         cptr += size;
  249.         *cptr = 0;
  250.         while ((found = strchr(where, '\n')))
  251.         {
  252.             *(found - 1) = 0;
  253.             fileptr = strrchr(where, ' ') + 1;
  254.             if (*where == '-' && match(file, fileptr, 1))
  255.             {
  256.                 if (!header)
  257.                 {
  258.                     fputs("File(s) to download:\n--------------------\n", stderr);
  259.                     header = 1;
  260.                 }
  261.                 fprintf(stderr, "%s\n", fileptr);
  262.                 strcat(matching, fileptr);
  263.                 strcat(matching, "\r");
  264.             }
  265.             where = found + 1;
  266.         }
  267.     }
  268. }
  269.  
  270. void timer_on(int fd)
  271. {
  272.     FD_ZERO(&fdset);
  273.     FD_SET(fd, &fdset);
  274.     ttimer.tv_sec = TMOUT;
  275.     ttimer.tv_usec = 0;
  276.     return;
  277. }
  278.